/**
 * 工作区面板组件
 *
 * 显示一行工作区指示器，展示工作区当前状态
 * 并允许在工作区之间切换。与Hyprland合成器配合使用。
 */
import { bind } from "astal";
import { Gtk } from "astal/gtk4";
import AstalHyprland from "gi://AstalHyprland";
import { Variable } from "astal";
import { ButtonProps } from "astal/gtk4/widget";
import { spacing } from "../../../variables";
import BarItem from "../../../components/BarItem";
import { range } from "../../../utils/range";

type WsButtonProps = ButtonProps & {
  ws: AstalHyprland.Workspace;
};

/**
 * 工作区按钮组件
 *
 * 表示单个工作区指示器，具有以下功能：
 * - 根据聚焦的工作区显示激活/非激活状态
 * - 当工作区客户端变化时更新外观
 * - 处理点击事件以聚焦工作区
 *
 * @param ws - Hyprland工作区对象
 * @param props - 额外的GTK按钮属性
 */
function WorkspaceButton({ ws, ...props }: WsButtonProps) {
  // 获取Hyprland实例
  const hyprland = AstalHyprland.get_default();

  // 根据工作区状态动态计算CSS类
  // 当聚焦的工作区或客户端变化时更新
  const classNames = Variable.derive(
    [bind(hyprland, "focusedWorkspace"), bind(hyprland, "clients")],
    (fws, _) => {
      const classes = ["indicator"];

      // 如果是聚焦的工作区，添加'active'类
      const active = fws.id == ws.id;
      active && classes.push("active");

      // 检查工作区是否有客户端(供将来使用)
      const occupied = hyprland.get_workspace(ws.id)?.get_clients().length > 0;
      occupied;
      return classes;
    }
  );

  return (
    <button
      // 动态CSS类，用于工作区状态样式
      cssClasses={classNames()}
      // 组件卸载时清理响应式变量
      onDestroy={() => classNames.drop()}
      // 垂直和水平居中按钮
      valign={Gtk.Align.CENTER}
      halign={Gtk.Align.CENTER}
      // 点击时聚焦工作区
      onClicked={() => ws.focus()}
      // 传递任何额外的props
      {...props}
    />
  );
}
/**
 * 工作区面板容器组件
 *
 * 在栏项目容器中渲染10个工作区指示器。
 * 每个指示器都是连接到模拟工作区的WorkspaceButton组件。
 *
 * 注意：使用模拟工作区用于演示/测试目的。
 * 实际应用中应连接到真实的Hyprland工作区。
 */
export default function WorkspacesPanelButton() {
  return (
    <BarItem>
      <box spacing={spacing} cssClasses={["bar_workspaces"]}>
        {range(10).map((i) => (
          <WorkspaceButton ws={AstalHyprland.Workspace.dummy(i + 1, null)} />
        ))}
      </box>
    </BarItem>
  );
}
